package com.glsc.ngateway.flowable.config;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.glsc.ngateway.common.base.domain.mysql.flowable.FlowableTenant;
import com.glsc.ngateway.flowable.service.FlowableTenantService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.form.api.FormRepositoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class FlowableTenantInit {
    private static Logger logger = LoggerFactory.getLogger(FlowableTenantInit.class);

    @Autowired
    FlowableTenantService flowableTenantService;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private FormRepositoryService formRepositoryService;

    /**
     * 本地修改调试的流程类型列表
     */
    @Value("${flowable.debugProcessKeyList}")
    private List<String> debugProcessKeyList;

    @Value("${flowable.debugProcessFlag}")
    private boolean debugProcessFlag;

    @Bean
    public void tenantConfig() {
        List<FlowableTenant> list = flowableTenantService.queryAllTenant();
        for (FlowableTenant ft : list) {
            try {
                if (debugProcessFlag) {//启用流程调试
                    if (debugProcessKeyList.contains(ft.getProcessDefinitionKey())) {//仅加载调试的流程
                        logger.info("部署调试流程版本流程：{}", ft.getProcessDefinitionKey());
                    } else {
                        logger.info("启用流程版本调试开发，不部署流程：{}", ft.getProcessDefinitionKey());
                        continue;
                    }
                }


                String md5 = SecureUtil.md5(ResourceUtil.getStream("processes/" + ft.getProcessDefinitionKey() + ".bpmn20.xml"));
                logger.info("流程" + ft.getProcessDefinitionKey() + ",计算md5:" + md5);
                logger.info("流程" + ft.getProcessDefinitionKey() + ",历史md5:" + ft.getProcessDefinitionMd5());
                if (StrUtil.equals(md5, ft.getProcessDefinitionMd5())) {
                    logger.info("流程定义初始化,md5一致,不更新:" + ft.getProcessDefinitionKey());
                    continue;
                }

                logger.info("流程定义初始化,md5不一致,更新:" + ft.getProcessDefinitionKey());
                DeploymentBuilder db = repositoryService.createDeployment().name(ft.getProcessDefinitionKey()).key(ft.getProcessDefinitionKey())
                        .addClasspathResource("processes/" + ft.getProcessDefinitionKey() + ".bpmn20.xml")
                        .tenantId(ft.getSysid());
                Deployment deployment = db.deploy();
                logger.info("flowable流程引擎初始化设置租户!" + ft.getProcessDefinitionKey() + "----" + ft.getSysid());

//                if (ft.getProcessDefinitionKey().equals("test-form")) {
//                    FormDeployment formDeployment = formRepositoryService.createDeployment()
//                            .name("definition-one")
//                            .addClasspathResource("forms/test.form")
//                            .parentDeploymentId(deployment.getId())
//                            .deploy();
//                    logger.info("flowable流程引擎初始化设置表单!" + ft.getProcessDefinitionKey() + "----" + ft.getSysid());
//                }
                ProcessDefinition ss = repositoryService.createProcessDefinitionQuery().processDefinitionKey(ft.getProcessDefinitionKey()).processDefinitionTenantId(ft.getSysid()).orderByProcessDefinitionVersion().desc().list().get(0);
                ft.setLatestProcessDefinitionId(ss.getId());
                ft.setProcessDefinitionMd5(md5);
                flowableTenantService.updateVersion(ft);
//                } else {
//                    logger.info("flowable流程引擎现有租户!" + ft.getProcessDefinitionKey() + "----" + ft.getSysid() + "----" + ft.getLatestProcessDefinitionId());
//                }
//                Map<String, PlatformTransactionManager> map = SpringUtil.getBeansOfType(PlatformTransactionManager.class);
//
//                Map<String, DataSource> map1 = SpringUtil.getBeansOfType(DataSource.class);
            } catch (Exception e) {
                logger.error("flowable流程引擎初始化失败!", e);
            }
        }
        logger.info("flowable流程引擎初始化设置租户完成!");
    }
}
